﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

//结构体内存对⻬
//结构体的对⻬规则：
//1. 结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处
//2. 其他成员变量要对⻬到某个数字（对⻬数）的整数倍的地址处。对⻬数 = 编译器默认的⼀个对⻬数与该成员变量⼤⼩的较⼩值。 VS中默认的值为 8,- Linux中 gcc 没有默认对⻬数，对⻬数就是成员⾃⾝的⼤⼩
//3. 结构体总⼤⼩为最⼤对⻬数（结构体中每个成员变量都有⼀个对⻬数，所有对⻬数中最⼤的）的整数倍。

//4. 如果嵌套了结构体的情况，嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处，结构体的整体⼤⼩就是所有最⼤对⻬数（含嵌套结构体中成员的对⻬数）的整数倍。
//struct S1
//{
//	char c1;
//	int i;
//	char c2;
//};
//struct S2
//{
//	char c1;
//	char c2;
//	int i;
//};
//struct S3
//{
//	double d;
//	char c;
//	int i;
//};
//int main()
//{
//	/*struct	S1 s1 = { 0 };
//	printf("%d\n", sizeof(s1));*///结果是12
//	struct	S2 s2 = { 0 };
//	printf("%d\n", sizeof(s2)); // 结果是8
// struct	S2 s3= { 0 };
//	printf("%d\n", sizeof(s3)); // 结果是16
//	return 0;
//}  

//struct S3
//{
//	double d;//8 8 8
//	char c;  //1 8 1
//	int i;   //4 8 4
//};
//
//struct S4
//{
//	char c1;
//	struct S3 s3;//16个字节，嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处（8）
//	double d;
//};
//int main()
//{
//	struct S4 s4 = { 0 };
//	printf("%zd\n", sizeof(s4));//
//	return 0;
//}

//修改对齐数
//#pragma pack(1)//设置默认对⻬数为1
//struct S
//{
//	char c1;
//	int i;
//	char c2;
//};
//#pragma pack()//取消设置的对⻬数，还原为默认
//int main()
//{
//	printf("%d\n", sizeof(struct S));//结果是6
//	return 0;
//}


//结构体传参
//struct S
//{
//	int arr[1000];
//	int n;
//	double d;
//};
//void print1(struct S tmp)
//{
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		printf("%d ", tmp.arr[i]);
//	}
//	printf("%d ", tmp.n);
//	printf("%lf ", tmp.d);
//}
//void print2(const struct S* ps)
//{
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		printf("%d ", ps->arr[i]);
//	}
//	printf("%d ", ps->n);
//	printf("%lf ", ps->d);
//}
//int main()
//{
//	struct S s = { {1,2,3,4,5},100,3.14 };
//	print1(s);
//	print2(&s);//结构体传参的时候，要传结构体的地址。
//}


//结构体实现位段:位段的声明和结构是类似的，有两个不同：1. 位段的成员必须是 int、unsigned int 或signed int ，在C99中位段成员的类型也可以选择其他类型。2. 位段的成员名后边有⼀个冒号和⼀个数字
//struct A//位（二进制位）段式结构
//{
//	int _a : 2;//占2个比特位
//	int _b : 5;//占5个比特位
//	int _c : 10;//占10个比特位
//	int _d : 30;//占30个比特位
//};
//int main()
//{
//	printf("%zd\n", sizeof(struct A));
//	return 0;
//}

//struct S// 位段的内存分配
//
//{
//	char a : 3;
//	char b : 4;
//	char c : 5;
//	char d : 4;
//};
//int main()
//{
//	struct S s = { 0 };
//	s.a = 10;
//	s.b = 12;
//	s.c = 3;
//	s.d = 4;
//}//不能对位段的成员使⽤&操作符


//联合体(共用体，所有成员共用一个空间)
//	union Un
//{
//		char c;
//		int i;
//};
//int main()
//{
//		//联合变量的定义
//		union Un u = { 0 };
//		//计算连个变量的⼤⼩
//		/*printf("%d\n", sizeof(u));//4
//		printf("%p\n", &u);
//		printf("%p\n", &(u.i));
//		printf("%p\n", &(u.c));*/
//
//		return 0;
//}


// 联合体⼤⼩的计算（联合的⼤⼩⾄少是最⼤成员的⼤⼩。当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候，就要对⻬到最⼤对⻬数的整数倍。）
//union Un1
//{
//	char c[5];
//	int i;
//};
//union Un2
//{
//	short c[7];
//	int i;
//};
//int main()
//{
//	printf("%d\n", sizeof(union Un1));//8
//	printf("%d\n", sizeof(union Un2));//16
//	return 0;
//}

